// 1822 [字符串] 简单.电话拦截
// http://oj.rnd.huawei.com/problems/1822/details终端产品的儿童电话手表有防骚扰特性，对电话呼入按如下规则处理：
// 注意:白名单有* 按照白名单长度比较, 没有*,按照较长的比较
//如果来电号码在白名单中，则电话要接通。否则电话自动拒接。
//现给定一组电话呼入和白名单操作的过程记录，格式为：
// C 13300000000 表示一条电话呼入记录。
// W 13144444444 表示添加一个号码到白名单中；
// W 03712832* 表示以 03712832 开头的号码都为白名单（*代表通配符，且仅在结尾）。
//请按照给定的过程记录，分别统计每个呼入号码的接通和拒接次数：
//每个号码的统计记录的格式如：
// 13144444444 1 3，以单个空格分隔，表示号码 13144444444 接通 1 次，拒接 3 次。
//统计记录的输出顺序：按照给定记录中号码首次呼入出现的先后顺序。
//输入第1行整数n，表示共有n条电话呼入和白名单操作记录，取值范围为[1, 3000]。
//随后n行是电话呼入和白名单操作记录。用例保证，号码仅为数字，长度范围为[3,11]
//输出每行一个字符串，代表一个呼入号码的统计记录
//输入 7
// C 13300000000
// W 13144444444
// C 13144444444
// C 03712832444
// C 03712832233
// W 03712832*
// C 03712832444
//输出
// 13300000000 0 1
// 13144444444 1 0
// 03712832444 1 1
// 03712832233 0 1

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define DEBUG
#ifdef DEBUG
#define PF(...) printf(__VA_ARGS__)
#else
#define PF(...)
#endif

struct Call {
  size_t index;  // from 1
                 //  string numb;
  int connect;
  int reject;
};

//   000000*
//   000000000
//
//   0111111
//   011111111

class Solution {
 public:
  bool existWhite(const vector<string>& vtWhite, const string& num) {
    auto it = std::find_if(vtWhite.begin(), vtWhite.end(), [num](string wt) {
      if (wt[0] == '*') {
        return true;
      }
      size_t nCmpLen = wt.length();
      if (wt[wt.length() - 1] == '*') {
        nCmpLen = wt.length() - 2;
      } else {
        nCmpLen = max(nCmpLen, num.length());
      }
      return wt.substr(0, nCmpLen).compare(num.substr(0, nCmpLen)) == 0;
    });
    return it != vtWhite.end();
  }

  // 待实现函数，在此函数中填入答题代码;
  vector<string> GetPhoneRecord(const vector<pair<char, string>>& records) {
    vector<string> vtWhite;
    map<string, Call> mapNumber;  // number, call
    for (size_t i = 0; i < records.size(); i++) {
      auto [ch, numb] = records[i];
      if (ch == 'C') {  // coming
        if (existWhite(vtWhite, numb)) {
          mapNumber[numb].connect++;
        } else {
          mapNumber[numb].reject++;
        }
        if (mapNumber[numb].index == 0) {
          mapNumber[numb].index = i + 1;
        }
      } else {  // white
        vtWhite.push_back(numb);
      }
    }

    typedef tuple<int, string, int, int> Record;
    vector<Record> vtNumber;  // id, number, conn, rej
    for (auto nu : mapNumber) {
      vtNumber.push_back(
          {nu.second.index, nu.first, nu.second.connect, nu.second.reject});
    }
    std::sort(vtNumber.begin(), vtNumber.end(),
              [](Record r1, Record r2) { return get<0>(r1) < get<0>(r2); });
    vector<string> result;
    for (auto [id, numb, conn, rej] : vtNumber) {
      result.push_back(numb + " " + to_string(conn) + " " + to_string(rej));
    }
    return result;
  }
};

// 以下为考题输入输出框架，此部分代码不建议改动
inline int ReadInt() {
  int number;
  std::cin >> number;
  return number;
}

template <typename T>
inline void WriteVector(const vector<T>& objects, char delimeter = ' ') {
  auto it = objects.begin();
  if (it == objects.end()) {
    return;
  }
  cout << *it;
  for (++it; it != objects.end(); ++it) {
    cout << delimeter << *it;
  }
  cout << endl;
}

int main() {
  int num = ReadInt();
  vector<pair<char, string>> records;
  for (int loop = 0; loop < num; loop++) {
    char op;
    string phone;

    cin >> op >> phone;
    records.push_back(make_pair(op, phone));
  }

  Solution solu;
  vector<string> result = solu.GetPhoneRecord(records);
  WriteVector(result, '\n');

  return 0;
}
